package com.delos.rbac.security;

import com.alibaba.fastjson.JSONObject;
import com.delos.rbac.error.ExceptionEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * SpringSecurity配置适配器
 *
 * @author zouyaowen
 * @date 2020-06-27
 */
@Configuration
@Slf4j
@EnableWebSecurity
public class SecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

    private static final String CODE = "code";
    private static final String MESSAGE = "message";

    @Autowired
    private TokenAuthenticationProvider tokenProvider;

    @Override
    public void configure(WebSecurity web) throws Exception {

        // 放行URL配置,以下为示例,一般用于静态资源放行
        //web.ignoring().antMatchers("/test/*");
        //web.ignoring().regexMatchers("^(?!(/user)).*$");
        web.ignoring().mvcMatchers("/user/*");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        log.info("security 配置加载");
        http.headers().cacheControl();
        http.csrf().disable();
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .disable()
                .httpBasic().disable()
                .exceptionHandling().authenticationEntryPoint((req, res, e) -> {
            res.setContentType("application/json;charset=utf-8");
            JSONObject resData = new JSONObject();
            Object code = req.getAttribute(CODE);
            Object message = req.getAttribute(MESSAGE);
            if (code != null && message != null) {
                resData.put(CODE, code);
                resData.put(MESSAGE, message);
            } else {
                resData.put(CODE, ExceptionEnum.AUTHENTICATION_ERROR.getCode());
                resData.put(MESSAGE, ExceptionEnum.AUTHENTICATION_ERROR.getMessage());
            }
            res.getWriter().write(resData.toString());
        });
        AuthenticationManager authenticationManager = authenticationManager();
        TokenFilter filter = new TokenFilter(authenticationManager);
        http.authenticationProvider(tokenProvider);
        http.addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class);
    }
}
